home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v16n10 / stringcl.asc < prev    next >
Encoding:
Text File  |  1991-09-10  |  9.0 KB  |  361 lines

  1. _PROPOSING A C++ STRING CLASS_
  2. by Steve Teale
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. class String {
  8. public:
  9. // String class constants
  10.     enum string_enum { all = INT_MAX };
  11.  
  12. // Constructors / destructor
  13.     String();                // make an empty String
  14.     String(const String&);       // make a String by copying another
  15.     String(const char *, int count = 0); 
  16.                                  // make a String from a regular C style string
  17.     String(char);            // make a String from a single char
  18.  
  19.     ~String();             // Clean up after a String goes out of scope
  20.  
  21. // Assignments
  22.     String &operator=(const String&);   // Assign from another String
  23.     String &operator=(const char *);    // Assign from a C style string
  24.     String &operator=(char);        // Assign from a single char
  25.     String &operator+=(const String&);  
  26.                                   // Concatenate a String to an existing String
  27.     String &operator+=(const char *);   
  28.                                     // Concatenate a C style string to a String
  29.     String &operator+=(char);       // Concatenate a char
  30.  
  31. // Other modifiers
  32.     String &insert(int pos, const String&);  // Insert into an existing string
  33.     String &insert(int pos, const char *);
  34.     String &insert(int pos, char);
  35.     String &remove(int pos, int count); // Remove from an existing string
  36.     String &truncate(int);      // Truncate a String
  37.  
  38. // Conversions
  39.     operator char*() const;    
  40.                      // Translate a String to a pointer to its first character
  41.     operator char() const;     // Translate a String to its initial character
  42.  
  43. // Mutators (make an existing String into a variant)
  44.     String upper() const;      // Make a new String by conversion to uppercase
  45.     String lower() const;
  46.     String operator()(int start, int len); 
  47.                    // Make a new String starting from start, of len characters
  48.  
  49. // Access individual characters
  50.     char &operator[](int);    // Access individual characters as if the String
  51.                   // were an array
  52.     char operator()(int);     // Get the character value of the i'th character.
  53.  
  54. // Searches
  55.     int match(const String&) const; 
  56. è                             // Return position of first non-matching character
  57.     int match(const char *) const;
  58.     int index(const String&, int pos = 0) const;
  59.     int index(const char *, int = 0) const;
  60.                              // Find the position of a substring or character
  61.     int index(char, int = 0) const;
  62.  
  63. // Statistics
  64.     int operator!() const;  // Test for an empty string
  65.     int length() const;     // Get the length of the String
  66.  
  67. // Some of the properties of a String are provided by functions which 
  68. // are friends of the String class
  69.  
  70. friend int strlen(const String&);   // Parallel the ANSI C string functions
  71. // etc
  72.  
  73. // Concatenations to make a new String
  74. friend String operator+(const String&, const String&);
  75. friend String operator+(const String&, const char *);
  76. friend String operator+(const char *, const String&);
  77.  
  78. // Boolean tests
  79. friend int operator==(const String&, const String&);
  80. friend int operator==(const String&, const char *);
  81. friend int operator==(const char *, const String&);
  82. friend int operator!=(const String&, const String&);
  83. friend int operator!=(const String&, const char *);
  84. friend int operator!=(const char *, const String&);
  85. friend int operator>(const String&, const String&);
  86. friend int operator>(const String&, const char *);
  87. friend int operator>(const char *, const String&);
  88. friend int operator<(const String&, const String&);
  89. friend int operator<(const String&, const char *);
  90. friend int operator<(const char *, const String&);
  91. friend int operator>=(const String&, const String&);
  92. friend int operator>=(const String&, const char *);
  93. friend int operator>=(const char *, const String&);
  94. friend int operator<=(const String&, const String&);
  95. friend int operator<=(const String&, const char *);
  96. friend int operator<=(const char *, const String&);
  97.  
  98. // Input/ output operations
  99. friend istream &operator>>(istream&, String&);
  100. friend ostream &operator<<(ostream&, const String&);
  101. };
  102.  
  103.  
  104. [LISTING TWO]
  105.  
  106.  
  107. #ifndef __STRING_HPP
  108. #define __STRING_HPP
  109. #include <limits.h>
  110.  
  111. èclass istream;   // forward declarations to avoid including all of iostream.hpp
  112. class ostream;
  113.  
  114. class srep {        // actual string representation
  115. friend class String;
  116. private:
  117.     srep(int, const char * = 0);
  118.     void *operator new(size_t cs, size_t ss = 0);
  119.  
  120.     int refs;
  121.     int length;
  122.     char body[1];
  123. };
  124.  
  125. class String {
  126. public:
  127.     // as above
  128. private:
  129.     char *body() const { return rp? rp->body: 0; }
  130.  
  131.     srep *rp;
  132.     static char dummy;
  133. };
  134.  
  135. inline int strlen(const String &s)
  136. {
  137.     return s.length();
  138. }
  139.  
  140. // and other friend functions which can conveniently be defined inline
  141.  
  142. #endif
  143.  
  144.  
  145.  
  146.  
  147. Figurσ 1
  148.  
  149. (a)
  150.  
  151.     String &operator=(char);
  152.     String &operator+=(char);
  153.  
  154.     String &insert(int, const String&);
  155.     String &insert(int, const char *);
  156.     String &insert(int, char);
  157.     String &remove(int, int);
  158.  
  159.     int operator!();
  160.  
  161.  
  162. (b)
  163.  
  164. String a;
  165.  
  166. èif (!a) ...;        // if a is empty string
  167. if (a) ...;     // if a is not empty - uses operator char *()
  168.  
  169.  
  170. (c)
  171.  
  172. friend int operator==(const String&, const String&);
  173. friend int operator==(const String&, const char *);
  174. friend int operator==(const char *, const String&);
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182. Figure 2
  183.  
  184. (a)
  185.  
  186.     String a;
  187.     ...
  188.     if (a == "whatever")
  189.         ...;
  190.  
  191. will cause a sequence something like:
  192.  
  193.     String temp = "whatever";   // constructor from const char *
  194.     if (operator==(a, temp))
  195.         ...;
  196.     // temp destructor call
  197.  
  198.  
  199. (b)
  200.  
  201. // two members
  202.     int operator==(const String&);
  203.     int operator==(const char *);
  204.  
  205. // and a friend
  206. friend int operator==(const char *, const String&);
  207.  
  208.  
  209.  
  210.  
  211. Figure 3
  212.  
  213.  
  214. (a)
  215.  
  216. String t;           // an empty string
  217. String a  = "good girl";    // initialized from a regular C style string
  218. String b = a;       // the copy constructor
  219. String c = '.';
  220.  
  221. èThis is the idiomatic usage.  It would have just the same effect to write:
  222.  
  223. String a("good girl");
  224. String b(a);
  225. String c('.');
  226.  
  227.  
  228. (b)
  229.  
  230.  
  231. String d("good girl", 4);
  232. // same effect as String d = "good";
  233.  
  234.  
  235. (c)
  236.  
  237.  
  238. String v = "abcd";
  239. v += 1;         // result "bcde" ?
  240.  
  241. String w = "provided"
  242. w  -= "vide"        // result "prod" ?
  243. w -= 'r';           // result "pod"   ?
  244.  
  245. String x = "1234567890"
  246. x <<= 1;            // result "2345678901"
  247.  
  248.  
  249.  
  250.  
  251. Figure 4
  252.  
  253. (a)
  254.  
  255.  
  256.     operator char();    // conversion to a char
  257.     operator char *();  // conversion to a char *
  258.  
  259. (b)
  260.  
  261.     void show(char c)
  262.     {
  263.         cout << c << ' ' << int(c) << endl;
  264.     }
  265.  
  266.     char array[4] = { '\0', '\0', '\0', '\0' };
  267.  
  268.     String nulls(array,4);
  269.     String empty;
  270.  
  271.     show(nulls);
  272.     show(empty);
  273.  
  274.  
  275.  
  276. èFigure 5
  277.  
  278. (a)
  279.  
  280.     String String::upper() const;
  281.     String String::lower() const;
  282.     String String::operator()(int start, int length) const;
  283.     String operator+(const String &a, const String &b);
  284.     String operator+(const String &a, const char *b);
  285.     String operator+(const char *a, const String &b);
  286.  
  287.  
  288. (b)
  289.  
  290.  
  291.     String a = "Cat";
  292.     a(0) = 'R';         // a gets "Rat"
  293.     // a.operator()(0) = 'R';
  294.  
  295.  
  296.  
  297.  
  298. Figure 6
  299.  
  300. (a)
  301.  
  302. String a = "The quick brown fox jumped over the lazy dogs back";
  303. String b = "The queen";
  304. String c = "lazy";
  305.  
  306. a.match(b);         // returns 7
  307. a.match("The quick");       // returns -1
  308.  
  309. a.index(b);         // returns -1
  310. a.index(c);         // returns 36
  311. a.index("The", 1);      // returns -1
  312. a.index("The");         // returns 0
  313. a.index("the");         // returns 32
  314. a.index('b');           // returns 10
  315. a.index('b',11);            // returns 46
  316.  
  317.  
  318. (b)
  319.  
  320.  
  321. // C style
  322.     char *s1 = "Joe", *s2 = "Fred";
  323.     if (s1 > s2) ...;           // legal, but not usually what was intended!
  324.     if (!strcmp(s1,s2)) ...;        // proper test for equality
  325.  
  326. // C++ style
  327.  
  328.     String s1 = "Joe", s2 = "Fred";
  329.     if (s1 > s2) ...;           // evaluates to true
  330.     if (s1 == s2) ...;          // proper test for equality
  331.  
  332.  
  333. Figure 6
  334.  
  335. (a)
  336.  
  337. String a = "The quick brown fox jumped over the lazy dogs back";
  338. String b = "The queen";
  339. String c = "lazy";
  340.  
  341. a.match(b);         // returns 7
  342. a.match("The quick");       // returns -1
  343.  
  344. a.index(b);         // returns -1
  345. a.index(c);         // returns 36
  346. a.index("The", 1);      // returns -1
  347. a.index("The");         // returns 0
  348. a.index("the");         // returns 32
  349. a.index('b');           // returns 10
  350. a.index('b',11);            // returns 46
  351.  
  352.  
  353. (b)
  354.  
  355.  
  356. // C style
  357.     char *s1 = "Joe", *s2 = "Fred";
  358.     if (s1 > s2) ...;           // legal, but not usually what was intended!
  359.     if (!strcmp(s1,s2)) ...;        // proper test for equality
  360.  
  361. // C++ style
  362.  
  363.     String s1 = "Joe", s2 = "Fred";
  364.     if (s1 > s2) ...;           // evaluates to true
  365.     if (s1 == s2) ...;          // proper test for equality
  366.